package com.xihuanjun.sdk.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * Copyright (C), 2024-08-26
 * FileName: MyUtils
 * Author:   溪浣君
 * Date:     2024-08-26 10:50
 * Description:
 */
public class PublicReflectionUtils {

    /**
     * 功能描述:
     * 〈根据输入对象，查找对象的属性。（包含父类属性）〉
     *
     * @param o 对象
     * @return : java.util.List<java.lang.reflect.Field> 对象属性
     * @author : All En
     * date : 2020/5/6 13:43
     */
    public static Field[] listReflectionField(Object o) throws ClassNotFoundException {
        Class clazz = o.getClass();
        Field[] fields = getAllFields(clazz);
        return fields;
    }


    public static Object getGetMethod(Object ob, String name) throws InvocationTargetException, IllegalAccessException {
        Method[] m = ob.getClass().getMethods();
        for (int i = 0; i < m.length; i++) {
            if (("get" + name).toLowerCase(Locale.ENGLISH).equals(m[i].getName().toLowerCase(Locale.ENGLISH))) {
                return m[i].invoke(ob);
            }
        }
        return null;

    }

    /**
     * 功能描述:
     * 〈获取输入对象的属性〉
     *
     * @param clazz 对象
     * @return : java.lang.reflect.Field[] 对象数据
     * @author : All En
     * date : 2020/5/6 13:43
     */
    private static Field[] getAllFields(Class<?> clazz) throws ClassNotFoundException {
        List<Field> fieldList = new ArrayList<>();
        //对象路径容器
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        //获取Field属性是对象属性。
//        fieldList.addAll(listClassForName(fieldList));
        Field[] fields = new Field[fieldList.size()];
        return fieldList.toArray(fields);
    }

    /**
     * 功能描述:
     * 〈判断Field属性，是否存为对象〉
     *
     * @param fieldList Field属性
     * @return : java.util.List<java.lang.String> 对象数据
     * @author : All En
     * date : 2020/5/6 14:12
     */
    private static List<Field> listClassForName(List<Field> fieldList) throws ClassNotFoundException {
        List<Field> comFieldList = new ArrayList<>();
        for (Field var : fieldList) {
            //判断类型是否为对象路径
            if (var.getGenericType().toString().contains("com")) {
                String[] split = var.getGenericType().toString().split(" ");
                if( split.length >2) {
                    Class z = Class.forName(split[1]);
                    while (z != null) {
                        comFieldList.addAll(new ArrayList<>(Arrays.asList(z.getDeclaredFields())));
                        z = z.getSuperclass();
                    }
                }
            }
        }
        return comFieldList;
    }


    /**
     * 功能描述:〈根据属性名获取对象的属性值〉
     *
     * @param fieldName 属性名
     * @param o         对象
     * @return : java.lang.Object 属性值
     * @author : LL
     * date : 2020.03.19 16:29
     */
    public static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            return null;
        }
    }



    /**
     * 功能描述:
     * 〈循环遍历对象中的属性值，〉
     *
     * @param o              对象
     * @param UnwantedColumn 对象中不需要的列名
     * @return : java.util.List<java.lang.String>
     * @author : All En
     * date : 2020/6/8 10:33
     */
    public static List<String> reflectionFieldResult(Object o, List<String> UnwantedColumn) throws ClassNotFoundException {
        List<String> data = new ArrayList<>();
        Field[] fields = listReflectionField(o);
        for (Field f : fields) {
            List<String> column = UnwantedColumn.stream().filter(v -> v.equals(f.getName())).collect(Collectors.toList());
            if (column.size() == 0) {
                Object value = getFieldValueByName(f.getName(), o);
                if (null == value)
                    data.add("");
                else
                    data.add(String.valueOf(value));
            }
        }
        return data;
    }

}